package goredis

import (
	"container/list"
	"fmt"
	"github.com/go-redis/redis"
	"go-micro.dev/v4/logger"
	"strconv"
	"sync"
	"time"
)

var (
	redisApiOnce sync.Once
)

var redisApi *RedisApi

type RedisApi struct {
	proxy *RedisProxy
}

func NewRedisApi() *RedisApi {
	if redisApi != nil {
		return redisApi
	}
	redisApiOnce.Do(func() {
		var redisProxy = NewRedisProxyRouterDefault(RedisClientTypeSingle)
		//var redisProxy = NewRedisProxyRouter(config.Instance.Redis)
		redisApi = &RedisApi{proxy: redisProxy}
		fmt.Println("-------------------------------")
	})
	return redisApi
}

func (r RedisApi) Pipeline() redis.Pipeliner {
	result := r.proxy.Router("Pipeline")
	return result.(redis.Pipeliner)
}

func (r RedisApi) Command() *redis.CommandsInfoCmd {
	result := r.proxy.Router("Command")
	return result.(*redis.CommandsInfoCmd)
}

func (r RedisApi) ClientGetName() *redis.StringCmd {
	result := r.proxy.Router("ClientGetName")
	return result.(*redis.StringCmd)
}

func (r RedisApi) Echo(message any) *redis.StringCmd {
	result := r.proxy.Router("Echo", message)
	return result.(*redis.StringCmd)
}

func (r RedisApi) Ping() *redis.StatusCmd {
	result := r.proxy.Router("Ping")
	return result.(*redis.StatusCmd)
}

func (r RedisApi) Quit() *redis.StatusCmd {
	result := r.proxy.Router("Quit")
	return result.(*redis.StatusCmd)
}

func (r RedisApi) Del(keys ...string) *redis.IntCmd {
	if r.isProxyCluster(keys...) {
		result := r.proxy.RouterPipeline("Del", keys...)
		return redis.NewIntCmd(result)
	}
	result := r.proxy.Router("Del", keys)
	return result.(*redis.IntCmd)

}

func (r RedisApi) isProxyCluster(keys ...string) bool {
	if r.proxy.IsProxyCluster() && len(keys) > 1 {
		return true
	}
	return false
}

func contains(slot redis.ClusterSlot, value int) bool {
	if value >= slot.Start && value <= slot.End {
		return true
	}
	return false
}

func (r RedisApi) Unlink(keys ...string) *redis.IntCmd {
	result := r.proxy.Router("Unlink", keys)
	return result.(*redis.IntCmd)
}

func (r RedisApi) Dump(key string) *redis.StringCmd {
	result := r.proxy.Router("Dump", key)
	return result.(*redis.StringCmd)
}

func (r RedisApi) Exists(keys ...string) *redis.IntCmd {
	if r.isProxyCluster(keys...) {
		result := r.proxy.RouterPipeline("Exists", keys...)
		return redis.NewIntCmd(result)
	}
	result := r.proxy.Router("Exists", keys)
	return result.(*redis.IntCmd)
}

// expire := client.Expire("key", 10*time.Second)
func (r RedisApi) Expire(key string, expiration time.Duration) *redis.BoolCmd {
	result := r.proxy.Router("Expire", key, expiration)
	return result.(*redis.BoolCmd)
}

// expireAt := client.ExpireAt("key", time.Now().Add(-time.Hour))
func (r RedisApi) ExpireAt(key string, time time.Time) *redis.BoolCmd {
	result := r.proxy.Router("ExpireAt", key, time)
	return result.(*redis.BoolCmd)
}

func (r RedisApi) Keys(pattern string) *redis.StringSliceCmd {
	result := r.proxy.Router("Keys", pattern)
	return result.(*redis.StringSliceCmd)
}

func (r RedisApi) Migrate(host, port, key string, db int64, timeout time.Duration) *redis.StatusCmd {
	result := r.proxy.Router("Migrate", host, port, key, db, timeout)
	return result.(*redis.StatusCmd)
}

func (r RedisApi) Move(key string, db int64) *redis.BoolCmd {
	result := r.proxy.Router("Move", key, db)
	return result.(*redis.BoolCmd)
}

func (r RedisApi) ObjectRefCount(key string) *redis.IntCmd {
	result := r.proxy.Router("ObjectRefCount", key)
	return result.(*redis.IntCmd)
}

func (r RedisApi) ObjectEncoding(key string) *redis.StringCmd {
	result := r.proxy.Router("ObjectEncoding", key)
	return result.(*redis.StringCmd)
}

func (r RedisApi) ObjectIdleTime(key string) *redis.DurationCmd {
	result := r.proxy.Router("ObjectIdleTime", key)
	return result.(*redis.DurationCmd)
}

func (r RedisApi) Persist(key string) *redis.BoolCmd {
	result := r.proxy.Router("Persist", key)
	return result.(*redis.BoolCmd)
}

func (r RedisApi) PExpire(key string, expiration time.Duration) *redis.BoolCmd {
	result := r.proxy.Router("PExpire", key, expiration)
	return result.(*redis.BoolCmd)
}

func (r RedisApi) PExpireAt(key string, time time.Time) *redis.BoolCmd {
	result := r.proxy.Router("PExpireAt", key, time)
	return result.(*redis.BoolCmd)
}

func (r RedisApi) PTTL(key string) *redis.DurationCmd {
	result := r.proxy.Router("PTTL", key)
	return result.(*redis.DurationCmd)
}

func (r RedisApi) RandomKey() *redis.StringCmd {
	result := r.proxy.Router("RandomKey")
	return result.(*redis.StringCmd)
}

func (r RedisApi) Rename(key, newKey string) *redis.StatusCmd {
	result := r.proxy.Router("Rename", key, newKey)
	return result.(*redis.StatusCmd)
}

func (r RedisApi) RenameNX(key, newKey string) *redis.BoolCmd {
	result := r.proxy.Router("Rename", key, newKey)
	return result.(*redis.BoolCmd)
}

func (r RedisApi) Restore(key string, ttl time.Duration, value string) *redis.StatusCmd {
	result := r.proxy.Router("Restore", key, ttl, value)
	return result.(*redis.StatusCmd)
}

func (r RedisApi) RestoreReplace(key string, ttl time.Duration, value string) *redis.StatusCmd {
	result := r.proxy.Router("RestoreReplace", key, ttl, value)
	return result.(*redis.StatusCmd)
}

func (r RedisApi) Sort(key string, sort *redis.Sort) *redis.StringSliceCmd {
	result := r.proxy.Router("Sort", key, sort)
	return result.(*redis.StringSliceCmd)
}

func (r RedisApi) SortStore(key, store string, sort *redis.Sort) *redis.IntCmd {
	result := r.proxy.Router("SortStore", key, store, sort)
	return result.(*redis.IntCmd)
}

func (r RedisApi) SortInterfaces(key string, sort *redis.Sort) *redis.SliceCmd {
	result := r.proxy.Router("SortInterfaces", key, sort)
	return result.(*redis.SliceCmd)
}

func (r RedisApi) Touch(keys ...string) *redis.IntCmd {
	result := r.proxy.Router("Touch", keys)
	return result.(*redis.IntCmd)
}

func (r RedisApi) TTL(key string) *redis.DurationCmd {
	result := r.proxy.Router("TTL", key)
	return result.(*redis.DurationCmd)
}

func (r RedisApi) Type(key string) *redis.StatusCmd {
	result := r.proxy.Router("Type", key)
	return result.(*redis.StatusCmd)
}

func (r RedisApi) Append(key, value string) *redis.IntCmd {
	result := r.proxy.Router("Append", key, value)
	return result.(*redis.IntCmd)
}

func (r RedisApi) BitCount(key string, bitCount *redis.BitCount) *redis.IntCmd {
	result := r.proxy.Router("BitCount", key, bitCount)
	return result.(*redis.IntCmd)
}

func (r RedisApi) BitOpAnd(destKey string, keys ...string) *redis.IntCmd {
	if r.isProxyCluster(keys...) {
		result := r.proxy.RouterPipeline("BitOpAnd", keys...)
		return redis.NewIntCmd(result)
	}
	result := r.proxy.Router("BitOpAnd", destKey, keys)
	return result.(*redis.IntCmd)
}

func (r RedisApi) BitOpOr(destKey string, keys ...string) *redis.IntCmd {
	result := r.proxy.Router("BitOpOr", destKey, keys)
	return result.(*redis.IntCmd)
}

func (r RedisApi) BitOpXor(destKey string, keys ...string) *redis.IntCmd {
	result := r.proxy.Router("BitOpXor", destKey, keys)
	return result.(*redis.IntCmd)
}

func (r RedisApi) BitOpNot(destKey string, key string) *redis.IntCmd {
	result := r.proxy.Router("BitOpNot", destKey, key)
	return result.(*redis.IntCmd)
}

func (r RedisApi) BitPos(key string, bit int64, pos ...int64) *redis.IntCmd {
	result := r.proxy.Router("BitPos", key, bit, pos)
	return result.(*redis.IntCmd)
}

func (r RedisApi) Decr(key string) *redis.IntCmd {
	result := r.proxy.Router("Decr", key)
	return result.(*redis.IntCmd)
}

func (r RedisApi) DecrBy(key string, decrement int64) *redis.IntCmd {
	result := r.proxy.Router("DecrBy", key, decrement)
	return result.(*redis.IntCmd)
}

func (r RedisApi) Get(key string) *redis.StringCmd {
	result := r.proxy.Router("Get", key)
	return result.(*redis.StringCmd)
}

func (r RedisApi) GetBit(key string, offset int64) *redis.IntCmd {
	result := r.proxy.Router("GetBit", key, offset)
	return result.(*redis.IntCmd)
}

func (r RedisApi) GetRange(key string, start, end int64) *redis.StringCmd {
	result := r.proxy.Router("GetRange", key, start, end)
	return result.(*redis.StringCmd)
}

func (r RedisApi) GetSet(key string, value any) *redis.StringCmd {
	result := r.proxy.Router("GetSet", key, value)
	return result.(*redis.StringCmd)
}

func (r RedisApi) Incr(key string) *redis.IntCmd {
	result := r.proxy.Router("GetSet", key)
	return result.(*redis.IntCmd)
}

func (r RedisApi) IncrBy(key string, value int64) *redis.IntCmd {
	result := r.proxy.Router("IncrBy", key, value)
	return result.(*redis.IntCmd)
}

func (r RedisApi) IncrByFloat(key string, value float64) *redis.FloatCmd {
	result := r.proxy.Router("IncrByFloat", key, value)
	return result.(*redis.FloatCmd)
}

func (r RedisApi) MSet(pairs ...any) *redis.StatusCmd {
	result := r.proxy.Router("MSet", pairs)
	return result.(*redis.StatusCmd)
}

func (r RedisApi) MSetNX(pairs ...any) *redis.BoolCmd {
	result := r.proxy.Router("MSetNX", pairs)
	return result.(*redis.BoolCmd)
}

func (r RedisApi) MGet(keys ...string) *redis.SliceCmd {
	if r.isProxyCluster(keys...) {
		result := r.proxy.RouterPipeline("MGet", keys...)
		return redis.NewSliceCmd(result)
	}
	result := r.proxy.Router("MGet", keys)
	return result.(*redis.SliceCmd)
}

// 默认缓存一天
// expire := client.Expire("key", 10*time.Second)
func (r RedisApi) Set(key string, value any) *redis.StatusCmd {
	var expiration time.Duration = 24 * time.Hour
	result := r.proxy.Router("Set", key, value, expiration)
	return result.(*redis.StatusCmd)
}

// 默认缓存一天
// expire := client.SetEx("key","value" 10*time.Second)
func (r RedisApi) SetEx(key string, value any, expiration time.Duration) *redis.StatusCmd {
	result := r.proxy.Router("Set", key, value, expiration)
	return result.(*redis.StatusCmd)
}

// 默认缓存一天 //expire := client.SetExTime("key", "value",10*time.Second)
func (r RedisApi) SetSe(key string, value any, second int) *redis.StatusCmd {
	var expiration time.Duration = 24 * time.Hour
	if second > 0 {
		expiration = time.Duration(second) * time.Second
	}
	result := r.proxy.Router("Set", key, value, expiration)
	return result.(*redis.StatusCmd)
}

func (r RedisApi) SetBit(key string, offset int64, value int) *redis.IntCmd {
	result := r.proxy.Router("SetBit", key, offset, value)
	return result.(*redis.IntCmd)
}

func (r RedisApi) SetNX(key string, value any, expiration time.Duration) *redis.BoolCmd {
	result := r.proxy.Router("SetNX", key, value, expiration)
	return result.(*redis.BoolCmd)
}

func (r RedisApi) SetXX(key string, value any, expiration time.Duration) *redis.BoolCmd {
	result := r.proxy.Router("SetXX", key, value, expiration)
	return result.(*redis.BoolCmd)
}

func (r RedisApi) SetRange(key string, offset int64, value string) *redis.IntCmd {
	result := r.proxy.Router("SetRange", key, offset, value)
	return result.(*redis.IntCmd)
}

func (r RedisApi) StrLen(key string) *redis.IntCmd {
	result := r.proxy.Router("StrLen", key)
	return result.(*redis.IntCmd)
}

func (r RedisApi) HDel(key string, fields ...string) *redis.IntCmd {
	result := r.proxy.Router("HDel", key, fields)
	return result.(*redis.IntCmd)
}

func (r RedisApi) HExists(key, field string) *redis.BoolCmd {
	result := r.proxy.Router("HExists", key, field)
	return result.(*redis.BoolCmd)
}

func (r RedisApi) HGet(key, field string) *redis.StringCmd {
	result := r.proxy.Router("HGet", key, field)
	return result.(*redis.StringCmd)
}
func (r RedisApi) HGetAll(key string) *redis.StringStringMapCmd {
	result := r.proxy.Router("HGetAll", key)
	return result.(*redis.StringStringMapCmd)
}

func (r RedisApi) HIncrBy(key, field string, incr int64) *redis.IntCmd {
	result := r.proxy.Router("HIncrBy", key, field, incr)
	return result.(*redis.IntCmd)
}

func (r RedisApi) HIncrByFloat(key, field string, incr float64) *redis.FloatCmd {
	result := r.proxy.Router("HIncrByFloat", key, field, incr)
	return result.(*redis.FloatCmd)
}

func (r RedisApi) HKeys(key string) *redis.StringSliceCmd {
	result := r.proxy.Router("HKeys", key)
	return result.(*redis.StringSliceCmd)
}

func (r RedisApi) HLen(key string) *redis.IntCmd {
	result := r.proxy.Router("HLen", key)
	return result.(*redis.IntCmd)
}

func (r RedisApi) HMSet(key string, fields map[string]any) *redis.StatusCmd {
	result := r.proxy.Router("HMSet", key, fields)
	return result.(*redis.StatusCmd)
}

func (r RedisApi) HSet(key, field string, value any) *redis.BoolCmd {
	result := r.proxy.Router("HSet", key, field, value)
	return result.(*redis.BoolCmd)
}

func (r RedisApi) HSetNX(key, field string, value any) *redis.BoolCmd {
	result := r.proxy.Router("HSetNX", key, field, value)
	return result.(*redis.BoolCmd)
}

func (r RedisApi) HVals(key string) *redis.StringSliceCmd {
	result := r.proxy.Router("HVals", key)
	return result.(*redis.StringSliceCmd)
}

func (r RedisApi) BLPop(timeout time.Duration, keys ...string) *redis.StringSliceCmd {
	result := r.proxy.Router("BLPop", timeout, keys)
	return result.(*redis.StringSliceCmd)
}

func (r RedisApi) BRPop(timeout time.Duration, keys ...string) *redis.StringSliceCmd {
	result := r.proxy.Router("BRPop", timeout, keys)
	return result.(*redis.StringSliceCmd)
}

func (r RedisApi) BRPopLPush(source, destination string, timeout time.Duration) *redis.StringCmd {
	result := r.proxy.Router("BRPopLPush", source, destination, timeout)
	return result.(*redis.StringCmd)
}

func (r RedisApi) LIndex(key string, index int64) *redis.StringCmd {
	result := r.proxy.Router("LIndex", key, index)
	return result.(*redis.StringCmd)
}

func (r RedisApi) LInsert(key, op string, pivot, value any) *redis.IntCmd {
	result := r.proxy.Router("LInsert", key, op, pivot, value)
	return result.(*redis.IntCmd)
}

func (r RedisApi) LInsertBefore(key string, pivot, value any) *redis.IntCmd {
	result := r.proxy.Router("LInsertBefore", key, pivot, value)
	return result.(*redis.IntCmd)
}

func (r RedisApi) LInsertAfter(key string, pivot, value any) *redis.IntCmd {
	result := r.proxy.Router("LInsertAfter", key, pivot, value)
	return result.(*redis.IntCmd)
}

func (r RedisApi) LLen(key string) *redis.IntCmd {
	result := r.proxy.Router("LLen", key)
	return result.(*redis.IntCmd)
}

func (r RedisApi) LPop(key string) *redis.StringCmd {
	result := r.proxy.Router("LPop", key)
	return result.(*redis.StringCmd)
}

func (r RedisApi) LPush(key string, values ...any) *redis.IntCmd {
	result := r.proxy.Router("LPush", key, values)
	return result.(*redis.IntCmd)
}

func (r RedisApi) LPushX(key string, value any) *redis.IntCmd {
	result := r.proxy.Router("LPushX", key, value)
	return result.(*redis.IntCmd)
}

func (r RedisApi) LRange(key string, start, stop int64) *redis.StringSliceCmd {
	result := r.proxy.Router("LRange", key, start, stop)
	return result.(*redis.StringSliceCmd)
}

func (r RedisApi) LRem(key string, count int64, value any) *redis.IntCmd {
	result := r.proxy.Router("LRem", key, count, value)
	return result.(*redis.IntCmd)
}

func (r RedisApi) LSet(key string, index int64, value any) *redis.StatusCmd {
	result := r.proxy.Router("LSet", key, index, value)
	return result.(*redis.StatusCmd)
}

func (r RedisApi) LTrim(key string, start, stop int64) *redis.StatusCmd {
	result := r.proxy.Router("LTrim", key, start, stop)
	return result.(*redis.StatusCmd)
}

func (r RedisApi) RPop(key string) *redis.StringCmd {
	result := r.proxy.Router("RPop", key)
	return result.(*redis.StringCmd)
}

func (r RedisApi) RPopLPush(source, destination string) *redis.StringCmd {
	result := r.proxy.Router("RPopLPush", source, destination)
	return result.(*redis.StringCmd)
}

func (r RedisApi) RPush(key string, values ...any) *redis.IntCmd {
	result := r.proxy.Router("RPush", key, values)
	return result.(*redis.IntCmd)
}

func (r RedisApi) RPushX(key string, value any) *redis.IntCmd {
	result := r.proxy.Router("RPushX", key, value)
	return result.(*redis.IntCmd)
}

func (r RedisApi) SAdd(key string, members ...any) *redis.IntCmd {
	result := r.proxy.Router("SAdd", key, members)
	return result.(*redis.IntCmd)
}

func (r RedisApi) SCard(key string) *redis.IntCmd {
	result := r.proxy.Router("SCard", key)
	return result.(*redis.IntCmd)
}

func (r RedisApi) SDiff(keys ...string) *redis.StringSliceCmd {
	result := r.proxy.Router("SDiff", keys)
	return result.(*redis.StringSliceCmd)
}

func (r RedisApi) SDiffStore(destination string, keys ...string) *redis.IntCmd {
	result := r.proxy.Router("SDiffStore", destination, keys)
	return result.(*redis.IntCmd)
}

func (r RedisApi) SInter(keys ...string) *redis.StringSliceCmd {
	result := r.proxy.Router("SInter", keys)
	return result.(*redis.StringSliceCmd)
}

func (r RedisApi) SInterStore(destination string, keys ...string) *redis.IntCmd {
	result := r.proxy.Router("SInterStore", destination, keys)
	return result.(*redis.IntCmd)
}

func (r RedisApi) SIsMember(key string, member any) *redis.BoolCmd {
	result := r.proxy.Router("SIsMember", key, member)
	return result.(*redis.BoolCmd)
}

func (r RedisApi) SMembers(key string) *redis.StringSliceCmd {
	result := r.proxy.Router("SMembers", key)
	return result.(*redis.StringSliceCmd)
}

func (r RedisApi) SMove(source, destination string, member any) *redis.BoolCmd {
	result := r.proxy.Router("SMove", source, destination, member)
	return result.(*redis.BoolCmd)
}

func (r RedisApi) SPop(key string) *redis.StringCmd {
	result := r.proxy.Router("SPop", key)
	return result.(*redis.StringCmd)
}

func (r RedisApi) SPopN(key string, count int64) *redis.StringSliceCmd {
	result := r.proxy.Router("SPopN", key, count)
	return result.(*redis.StringSliceCmd)
}

func (r RedisApi) SRandMember(key string) *redis.StringCmd {
	result := r.proxy.Router("SRandMember", key)
	return result.(*redis.StringCmd)
}

func (r RedisApi) SRandMemberN(key string, count int64) *redis.StringSliceCmd {
	result := r.proxy.Router("SRandMemberN", key, count)
	return result.(*redis.StringSliceCmd)
}

func (r RedisApi) SRem(key string, members ...any) *redis.IntCmd {
	result := r.proxy.Router("SRem", key, members)
	return result.(*redis.IntCmd)
}

func (r RedisApi) SUnion(keys ...string) *redis.StringSliceCmd {
	result := r.proxy.Router("SUnion", keys)
	return result.(*redis.StringSliceCmd)
}

func (r RedisApi) SUnionStore(destination string, keys ...string) *redis.IntCmd {
	result := r.proxy.Router("SUnionStore", destination, keys)
	return result.(*redis.IntCmd)
}

func (r RedisApi) XAdd(args *redis.XAddArgs) *redis.StringCmd {
	result := r.proxy.Router("XAdd", args)
	return result.(*redis.StringCmd)
}

func (r RedisApi) XDel(stream string, ids ...string) *redis.IntCmd {
	result := r.proxy.Router("XDel", stream, ids)
	return result.(*redis.IntCmd)
}

func (r RedisApi) XLen(stream string) *redis.IntCmd {
	result := r.proxy.Router("XLen", stream)
	return result.(*redis.IntCmd)
}

func (r RedisApi) XRange(stream, start, stop string) *redis.XMessageSliceCmd {
	result := r.proxy.Router("XRange", stream, start, stop)
	return result.(*redis.XMessageSliceCmd)
}

func (r RedisApi) XRangeN(stream, start, stop string, count int64) *redis.XMessageSliceCmd {
	result := r.proxy.Router("XRangeN", stream, start, stop, count)
	return result.(*redis.XMessageSliceCmd)
}

func (r RedisApi) XRevRange(stream string, start, stop string) *redis.XMessageSliceCmd {
	result := r.proxy.Router("XRevRange", stream, start, stop)
	return result.(*redis.XMessageSliceCmd)
}

func (r RedisApi) XRevRangeN(stream string, start, stop string, count int64) *redis.XMessageSliceCmd {
	result := r.proxy.Router("XRevRangeN", stream, start, stop, count)
	return result.(*redis.XMessageSliceCmd)
}

func (r RedisApi) XRead(args *redis.XReadArgs) *redis.XStreamSliceCmd {
	result := r.proxy.Router("XRead", args)
	return result.(*redis.XStreamSliceCmd)
}

func (r RedisApi) XReadStreams(streams ...string) *redis.XStreamSliceCmd {
	result := r.proxy.Router("XReadStreams", streams)
	return result.(*redis.XStreamSliceCmd)
}

func (r RedisApi) XGroupCreate(stream, group, start string) *redis.StatusCmd {
	result := r.proxy.Router("XGroupCreate", stream, group, start)
	return result.(*redis.StatusCmd)
}

func (r RedisApi) XGroupCreateMkStream(stream, group, start string) *redis.StatusCmd {
	result := r.proxy.Router("XGroupCreateMkStream", stream, group, start)
	return result.(*redis.StatusCmd)
}

func (r RedisApi) XGroupSetID(stream, group, start string) *redis.StatusCmd {
	result := r.proxy.Router("XGroupSetID", stream, group, start)
	return result.(*redis.StatusCmd)
}

func (r RedisApi) XGroupDestroy(stream, group string) *redis.IntCmd {
	result := r.proxy.Router("XGroupDestroy", stream, group)
	return result.(*redis.IntCmd)
}

func (r RedisApi) XGroupDelConsumer(stream, group, consumer string) *redis.IntCmd {
	result := r.proxy.Router("XGroupDelConsumer", stream, group, consumer)
	return result.(*redis.IntCmd)
}

func (r RedisApi) XReadGroup(args *redis.XReadGroupArgs) *redis.XStreamSliceCmd {
	result := r.proxy.Router("XReadGroup", args)
	return result.(*redis.XStreamSliceCmd)
}

func (r RedisApi) XAck(stream, group string, ids ...string) *redis.IntCmd {
	result := r.proxy.Router("XAck", stream, group, ids)
	return result.(*redis.IntCmd)
}

func (r RedisApi) XPending(stream, group string) *redis.XPendingCmd {
	result := r.proxy.Router("XPending", stream, group)
	return result.(*redis.XPendingCmd)
}

func (r RedisApi) XPendingExt(args *redis.XPendingExtArgs) *redis.XPendingExtCmd {
	result := r.proxy.Router("XPendingExt", args)
	return result.(*redis.XPendingExtCmd)
}

func (r RedisApi) XClaim(args *redis.XClaimArgs) *redis.XMessageSliceCmd {
	result := r.proxy.Router("XClaim", args)
	return result.(*redis.XMessageSliceCmd)
}

func (r RedisApi) XClaimJustID(args *redis.XClaimArgs) *redis.StringSliceCmd {
	result := r.proxy.Router("XClaimJustID", args)
	return result.(*redis.StringSliceCmd)
}

func (r RedisApi) XTrim(key string, maxLen int64) *redis.IntCmd {
	result := r.proxy.Router("XTrim", key, maxLen)
	return result.(*redis.IntCmd)
}

func (r RedisApi) XTrimApprox(key string, maxLen int64) *redis.IntCmd {
	result := r.proxy.Router("XTrimApprox", key, maxLen)
	return result.(*redis.IntCmd)
}

func (r RedisApi) BZPopMax(timeout time.Duration, keys ...string) *redis.ZWithKeyCmd {
	result := r.proxy.Router("BZPopMax", timeout, keys)
	return result.(*redis.ZWithKeyCmd)
}

func (r RedisApi) BZPopMin(timeout time.Duration, keys ...string) *redis.ZWithKeyCmd {
	result := r.proxy.Router("BZPopMin", timeout, keys)
	return result.(*redis.ZWithKeyCmd)
}

func (r RedisApi) ZAdd(key string, members ...redis.Z) *redis.IntCmd {
	result := r.proxy.Router("ZAdd", key, members)
	return result.(*redis.IntCmd)
}

func (r RedisApi) ZAddNX(key string, members ...redis.Z) *redis.IntCmd {
	result := r.proxy.Router("ZAddNX", key, members)
	return result.(*redis.IntCmd)
}

func (r RedisApi) ZAddXX(key string, members ...redis.Z) *redis.IntCmd {
	result := r.proxy.Router("ZAddXX", key, members)
	return result.(*redis.IntCmd)
}

func (r RedisApi) ZAddCh(key string, members ...redis.Z) *redis.IntCmd {
	result := r.proxy.Router("ZAddCh", key, members)
	return result.(*redis.IntCmd)
}

func (r RedisApi) ZAddNXCh(key string, members ...redis.Z) *redis.IntCmd {
	result := r.proxy.Router("ZAddNXCh", key, members)
	return result.(*redis.IntCmd)
}

func (r RedisApi) ZAddXXCh(key string, members ...redis.Z) *redis.IntCmd {
	result := r.proxy.Router("ZAddXXCh", key, members)
	return result.(*redis.IntCmd)
}

func (r RedisApi) ZIncr(key string, member redis.Z) *redis.FloatCmd {
	result := r.proxy.Router("ZIncr", key, member)
	return result.(*redis.FloatCmd)
}

func (r RedisApi) ZIncrNX(key string, member redis.Z) *redis.FloatCmd {
	result := r.proxy.Router("ZIncrNX", key, member)
	return result.(*redis.FloatCmd)
}

func (r RedisApi) ZIncrXX(key string, member redis.Z) *redis.FloatCmd {
	result := r.proxy.Router("ZIncrXX", key, member)
	return result.(*redis.FloatCmd)
}

func (r RedisApi) ZCard(key string) *redis.IntCmd {
	result := r.proxy.Router("ZCard", key)
	return result.(*redis.IntCmd)
}

func (r RedisApi) ZCount(key, min, max string) *redis.IntCmd {
	result := r.proxy.Router("ZCount", key, min, max)
	return result.(*redis.IntCmd)
}

func (r RedisApi) ZLexCount(key, min, max string) *redis.IntCmd {
	result := r.proxy.Router("ZLexCount", key, min, max)
	return result.(*redis.IntCmd)
}

func (r RedisApi) ZIncrBy(key string, increment float64, member string) *redis.FloatCmd {
	result := r.proxy.Router("ZIncrBy", key, increment, member)
	return result.(*redis.FloatCmd)
}

func (r RedisApi) ZInterStore(destination string, store redis.ZStore, keys ...string) *redis.IntCmd {
	result := r.proxy.Router("ZInterStore", destination, store, keys)
	return result.(*redis.IntCmd)
}

func (r RedisApi) ZPopMax(key string, count ...int64) *redis.ZSliceCmd {
	result := r.proxy.Router("ZPopMax", key, count)
	return result.(*redis.ZSliceCmd)
}

func (r RedisApi) ZPopMin(key string, count ...int64) *redis.ZSliceCmd {
	result := r.proxy.Router("ZPopMin", key, count)
	return result.(*redis.ZSliceCmd)
}

func (r RedisApi) ZRange(key string, start, stop int64) *redis.StringSliceCmd {
	result := r.proxy.Router("ZRange", key, start, stop)
	return result.(*redis.StringSliceCmd)
}

func (r RedisApi) ZRangeWithScores(key string, start, stop int64) *redis.ZSliceCmd {
	result := r.proxy.Router("ZRangeWithScores", key, start, stop)
	return result.(*redis.ZSliceCmd)
}

func (r RedisApi) ZRangeByScore(key string, opt redis.ZRangeBy) *redis.StringSliceCmd {
	result := r.proxy.Router("ZRangeByScore", key, opt)
	return result.(*redis.StringSliceCmd)
}

func (r RedisApi) ZRangeByLex(key string, opt redis.ZRangeBy) *redis.StringSliceCmd {
	result := r.proxy.Router("ZRangeByLex", key, opt)
	return result.(*redis.StringSliceCmd)
}

func (r RedisApi) ZRangeByScoreWithScores(key string, opt redis.ZRangeBy) *redis.ZSliceCmd {
	result := r.proxy.Router("ZRangeByScoreWithScores", key, opt)
	return result.(*redis.ZSliceCmd)
}

func (r RedisApi) ZRank(key, member string) *redis.IntCmd {
	result := r.proxy.Router("ZRank", key, member)
	return result.(*redis.IntCmd)
}

func (r RedisApi) ZRem(key string, members ...any) *redis.IntCmd {
	result := r.proxy.Router("ZRem", key, members)
	return result.(*redis.IntCmd)
}

func (r RedisApi) ZRemRangeByRank(key string, start, stop int64) *redis.IntCmd {
	result := r.proxy.Router("ZRemRangeByRank", key, start, stop)
	return result.(*redis.IntCmd)
}

func (r RedisApi) ZRemRangeByScore(key, min, max string) *redis.IntCmd {
	result := r.proxy.Router("ZRemRangeByScore", key, min, max)
	return result.(*redis.IntCmd)
}

func (r RedisApi) ZRemRangeByLex(key, min, max string) *redis.IntCmd {
	result := r.proxy.Router("ZRemRangeByLex", key, min, max)
	return result.(*redis.IntCmd)
}

func (r RedisApi) ZRevRange(key string, start, stop int64) *redis.StringSliceCmd {
	result := r.proxy.Router("ZRevRange", key, start, stop)
	return result.(*redis.StringSliceCmd)
}

func (r RedisApi) ZRevRangeWithScores(key string, start, stop int64) *redis.ZSliceCmd {
	result := r.proxy.Router("ZRevRangeWithScores", key, start, stop)
	return result.(*redis.ZSliceCmd)
}

func (r RedisApi) ZRevRangeByScore(key string, opt redis.ZRangeBy) *redis.StringSliceCmd {
	result := r.proxy.Router("ZRevRangeByScore", key, opt)
	return result.(*redis.StringSliceCmd)
}

func (r RedisApi) ZRevRangeByLex(key string, opt redis.ZRangeBy) *redis.StringSliceCmd {
	result := r.proxy.Router("ZRevRangeByLex", key, opt)
	return result.(*redis.StringSliceCmd)
}

func (r RedisApi) ZRevRangeByScoreWithScores(key string, opt redis.ZRangeBy) *redis.ZSliceCmd {
	result := r.proxy.Router("ZRevRangeByScoreWithScores", key, opt)
	return result.(*redis.ZSliceCmd)
}

func (r RedisApi) ZRevRank(key, member string) *redis.IntCmd {
	result := r.proxy.Router("ZRevRank", key, member)
	return result.(*redis.IntCmd)
}

func (r RedisApi) ZScore(key, member string) *redis.FloatCmd {
	result := r.proxy.Router("ZScore", key, member)
	return result.(*redis.FloatCmd)
}

func (r RedisApi) ZUnionStore(dest string, store redis.ZStore, keys ...string) *redis.IntCmd {
	result := r.proxy.Router("ZUnionStore", dest, store, keys)
	return result.(*redis.IntCmd)
}

func (r RedisApi) PFAdd(key string, els ...any) *redis.IntCmd {
	result := r.proxy.Router("PFAdd", key, els)
	return result.(*redis.IntCmd)
}

func (r RedisApi) PFCount(keys ...string) *redis.IntCmd {
	result := r.proxy.Router("PFCount", keys)
	return result.(*redis.IntCmd)
}

func (r RedisApi) PFMerge(dest string, keys ...string) *redis.StatusCmd {
	result := r.proxy.Router("PFMerge", dest, keys)
	return result.(*redis.StatusCmd)
}

func (r RedisApi) BgRewriteAOF() *redis.StatusCmd {
	result := r.proxy.Router("BgRewriteAOF")
	return result.(*redis.StatusCmd)
}

func (r RedisApi) BgSave() *redis.StatusCmd {
	result := r.proxy.Router("BgSave")
	return result.(*redis.StatusCmd)
}

func (r RedisApi) ClientKill(ipPort string) *redis.StatusCmd {
	result := r.proxy.Router("ClientKill", ipPort)
	return result.(*redis.StatusCmd)
}

func (r RedisApi) ClientKillByFilter(keys ...string) *redis.IntCmd {
	if r.isProxyCluster(keys...) {
		result := r.proxy.RouterPipeline("ClientKillByFilter", keys...)
		return redis.NewIntCmd(result)
	}
	result := r.proxy.Router("ClientKillByFilter", keys)
	return result.(*redis.IntCmd)
}

func (r RedisApi) ClientList() *redis.StringCmd {
	result := r.proxy.Router("ClientList")
	return result.(*redis.StringCmd)
}

func (r RedisApi) ClientPause(dur time.Duration) *redis.BoolCmd {
	result := r.proxy.Router("ClientPause", dur)
	return result.(*redis.BoolCmd)
}

func (r RedisApi) ClientID() *redis.IntCmd {
	result := r.proxy.Router("ClientID")
	return result.(*redis.IntCmd)
}

func (r RedisApi) ConfigResetStat() *redis.StatusCmd {
	result := r.proxy.Router("ConfigResetStat")
	return result.(*redis.StatusCmd)
}

func (r RedisApi) ConfigSet(parameter, value string) *redis.StatusCmd {
	result := r.proxy.Router("ConfigSet", parameter, value)
	return result.(*redis.StatusCmd)
}

func (r RedisApi) ConfigRewrite() *redis.StatusCmd {
	result := r.proxy.Router("ConfigRewrite")
	return result.(*redis.StatusCmd)
}

func (r RedisApi) DBSize() *redis.IntCmd {
	result := r.proxy.Router("DBSize")
	return result.(*redis.IntCmd)
}

func (r RedisApi) FlushAll() *redis.StatusCmd {
	result := r.proxy.Router("FlushAll")
	return result.(*redis.StatusCmd)
}

func (r RedisApi) FlushAllAsync() *redis.StatusCmd {
	result := r.proxy.Router("FlushAllAsync")
	return result.(*redis.StatusCmd)
}

func (r RedisApi) FlushDB() *redis.StatusCmd {
	result := r.proxy.Router("FlushDB")
	return result.(*redis.StatusCmd)
}

func (r RedisApi) FlushDBAsync() *redis.StatusCmd {
	result := r.proxy.Router("FlushDBAsync")
	return result.(*redis.StatusCmd)
}

func (r RedisApi) Info(section ...string) *redis.StringCmd {
	result := r.proxy.Router("Info", section)
	return result.(*redis.StringCmd)
}

func (r RedisApi) LastSave() *redis.IntCmd {
	result := r.proxy.Router("LastSave")
	return result.(*redis.IntCmd)
}

func (r RedisApi) Save() *redis.StatusCmd {
	result := r.proxy.Router("ZAddSave")
	return result.(*redis.StatusCmd)
}

func (r RedisApi) Shutdown() *redis.StatusCmd {
	result := r.proxy.Router("Shutdown")
	return result.(*redis.StatusCmd)
}

func (r RedisApi) ShutdownSave() *redis.StatusCmd {
	result := r.proxy.Router("ShutdownSave")
	return result.(*redis.StatusCmd)
}

func (r RedisApi) ShutdownNoSave() *redis.StatusCmd {
	result := r.proxy.Router("ShutdownNoSave")
	return result.(*redis.StatusCmd)
}

func (r RedisApi) SlaveOf(host, port string) *redis.StatusCmd {
	result := r.proxy.Router("SlaveOf", host, port)
	return result.(*redis.StatusCmd)
}

func (r RedisApi) Time() *redis.TimeCmd {
	result := r.proxy.Router("Time")
	return result.(*redis.TimeCmd)
}

func (r RedisApi) Eval(script string, keys []string, args ...any) *redis.Cmd {
	result := r.proxy.Router("Eval", script, keys, args)
	return result.(*redis.Cmd)
}

func (r RedisApi) EvalSha(sha1 string, keys []string, args ...any) *redis.Cmd {
	result := r.proxy.Router("EvalSha", sha1, keys, args)
	return result.(*redis.Cmd)
}

func (r RedisApi) ScriptFlush() *redis.StatusCmd {
	result := r.proxy.Router("ScriptFlush")
	return result.(*redis.StatusCmd)
}

func (r RedisApi) ScriptKill() *redis.StatusCmd {
	result := r.proxy.Router("ScriptKill")
	return result.(*redis.StatusCmd)
}

func (r RedisApi) ScriptLoad(script string) *redis.StringCmd {
	result := r.proxy.Router("ScriptLoad", script)
	return result.(*redis.StringCmd)
}

func (r RedisApi) DebugObject(key string) *redis.StringCmd {
	result := r.proxy.Router("DebugObject", key)
	return result.(*redis.StringCmd)
}

func (r RedisApi) Publish(channel string, message any) *redis.IntCmd {
	result := r.proxy.Router("Publish", channel, message)
	return result.(*redis.IntCmd)
}

func (r RedisApi) PubSubChannels(pattern string) *redis.StringSliceCmd {
	result := r.proxy.Router("PubSubChannels", pattern)
	return result.(*redis.StringSliceCmd)
}

func (r RedisApi) PubSubNumPat() *redis.IntCmd {
	result := r.proxy.Router("PubSubNumPat")
	return result.(*redis.IntCmd)
}

func (r RedisApi) ClusterSlots() *redis.ClusterSlotsCmd {
	result := r.proxy.Router("ClusterSlots")
	return result.(*redis.ClusterSlotsCmd)
}

func (r RedisApi) ClusterNodes() *redis.StringCmd {
	result := r.proxy.Router("ClusterNodes")
	return result.(*redis.StringCmd)
}

func (r RedisApi) ClusterMeet(host, port string) *redis.StatusCmd {
	result := r.proxy.Router("ClusterMeet", host, port)
	return result.(*redis.StatusCmd)
}

func (r RedisApi) ClusterForget(nodeID string) *redis.StatusCmd {
	result := r.proxy.Router("ClusterForget", nodeID)
	return result.(*redis.StatusCmd)
}

func (r RedisApi) ClusterReplicate(nodeID string) *redis.StatusCmd {
	result := r.proxy.Router("ClusterReplicate", nodeID)
	return result.(*redis.StatusCmd)
}

func (r RedisApi) ClusterResetSoft() *redis.StatusCmd {
	result := r.proxy.Router("ClusterResetSoft")
	return result.(*redis.StatusCmd)
}

func (r RedisApi) ClusterResetHard() *redis.StatusCmd {
	result := r.proxy.Router("ClusterResetHard")
	return result.(*redis.StatusCmd)
}

func (r RedisApi) ClusterInfo() *redis.StringCmd {
	result := r.proxy.Router("ClusterInfo")
	return result.(*redis.StringCmd)
}

func (r RedisApi) ClusterKeySlot(key string) *redis.IntCmd {
	result := r.proxy.Router("ClusterKeySlot", key)
	return result.(*redis.IntCmd)
}

func (r RedisApi) ClusterGetKeysInSlot(slot int, count int) *redis.StringSliceCmd {
	result := r.proxy.Router("ClusterGetKeysInSlot", slot, count)
	return result.(*redis.StringSliceCmd)
}

func (r RedisApi) ClusterCountFailureReports(nodeID string) *redis.IntCmd {
	result := r.proxy.Router("ClusterCountFailureReports", nodeID)
	return result.(*redis.IntCmd)
}

func (r RedisApi) ClusterCountKeysInSlot(slot int) *redis.IntCmd {
	result := r.proxy.Router("ClusterCountKeysInSlot", slot)
	return result.(*redis.IntCmd)
}

func (r RedisApi) ClusterDelSlots(slots ...int) *redis.StatusCmd {
	result := r.proxy.Router("ClusterDelSlots", slots)
	return result.(*redis.StatusCmd)
}

func (r RedisApi) ClusterDelSlotsRange(min, max int) *redis.StatusCmd {
	result := r.proxy.Router("ClusterDelSlotsRange", min, max)
	return result.(*redis.StatusCmd)
}

func (r RedisApi) ClusterSaveConfig() *redis.StatusCmd {
	result := r.proxy.Router("ClusterSaveConfig")
	return result.(*redis.StatusCmd)
}

func (r RedisApi) ClusterSlaves(nodeID string) *redis.StringSliceCmd {
	result := r.proxy.Router("ClusterSlaves", nodeID)
	return result.(*redis.StringSliceCmd)
}

func (r RedisApi) ClusterFailover() *redis.StatusCmd {
	result := r.proxy.Router("ClusterFailover")
	return result.(*redis.StatusCmd)
}

func (r RedisApi) ClusterAddSlots(slots ...int) *redis.StatusCmd {
	result := r.proxy.Router("ClusterAddSlots", slots)
	return result.(*redis.StatusCmd)
}

func (r RedisApi) ClusterAddSlotsRange(min, max int) *redis.StatusCmd {
	result := r.proxy.Router("ClusterAddSlotsRange", min, max)
	return result.(*redis.StatusCmd)
}

func (r RedisApi) GeoAdd(key string, geoLocation ...*redis.GeoLocation) *redis.IntCmd {
	result := r.proxy.Router("GeoAdd", key, geoLocation)
	return result.(*redis.IntCmd)
}

func (r RedisApi) GeoPos(key string, members ...string) *redis.GeoPosCmd {
	result := r.proxy.Router("GeoPos", key, members)
	return result.(*redis.GeoPosCmd)
}

func (r RedisApi) GeoRadius(key string, longitude, latitude float64, query *redis.GeoRadiusQuery) *redis.GeoLocationCmd {
	result := r.proxy.Router("GeoRadius", key, latitude, latitude, query)
	return result.(*redis.GeoLocationCmd)
}

func (r RedisApi) GeoRadiusRO(key string, longitude, latitude float64, query *redis.GeoRadiusQuery) *redis.GeoLocationCmd {
	result := r.proxy.Router("ZAdd", key, longitude, latitude, query)
	return result.(*redis.GeoLocationCmd)
}

func (r RedisApi) GeoRadiusByMember(key, member string, query *redis.GeoRadiusQuery) *redis.GeoLocationCmd {
	result := r.proxy.Router("GeoRadiusByMember", key, member, query)
	return result.(*redis.GeoLocationCmd)
}

func (r RedisApi) GeoRadiusByMemberRO(key, member string, query *redis.GeoRadiusQuery) *redis.GeoLocationCmd {
	result := r.proxy.Router("GeoRadiusByMemberRO", key, member, query)
	return result.(*redis.GeoLocationCmd)
}

func (r RedisApi) GeoDist(key string, member1, member2, unit string) *redis.FloatCmd {
	result := r.proxy.Router("GeoDist", key, member1, member2, unit)
	return result.(*redis.FloatCmd)
}

func (r RedisApi) GeoHash(key string, members ...string) *redis.StringSliceCmd {
	result := r.proxy.Router("GeoHash", key, members)
	return result.(*redis.StringSliceCmd)
}

func (r RedisApi) ReadOnly() *redis.StatusCmd {
	result := r.proxy.Router("ReadOnly")
	return result.(*redis.StatusCmd)
}

func (r RedisApi) ReadWrite() *redis.StatusCmd {
	result := r.proxy.Router("ReadWrite")
	return result.(*redis.StatusCmd)
}

func (r RedisApi) MemoryUsage(key string, samples ...int) *redis.IntCmd {
	result := r.proxy.Router("MemoryUsage", key, samples)
	return result.(*redis.IntCmd)
}

func (r RedisApi) DelPipeline(keys ...string) []redis.Cmder {
	var proxy = r.proxy.proxyFactory.RedisClientRouter()
	client, ok := proxy.(*redis.ClusterClient)
	if ok {
		pipeline := client.Pipeline()
		for _, key := range keys {
			del := pipeline.Del(key)
			fmt.Println("DelPipeline   del >>", del)
		}
		result, err := pipeline.Exec()
		fmt.Println("DelPipeline   result >>", result)
		if err != nil {
			return nil
		}
		return result
	}
	return nil
}

func (r RedisApi) KeySlot(keys []string) map[int]list.List {
	// 将key对应相同slot的放在一起

	var proxy = r.proxy.proxyFactory.RedisClientRouter()
	clusterClient, ok := proxy.(*redis.ClusterClient)
	if !ok {
		panic(ok)
	}
	slotMap := make(map[int]list.List)
	slotValues := clusterClient.ClusterSlots().Val()
	for i, slotValue := range slotValues {
		var slotValueList, ok = slotMap[i]
		if !ok {
			slotValueList = list.List{}
		}
		for _, key := range keys {
			slotNumber := int(clusterClient.ClusterKeySlot(key).Val())
			if contains(slotValue, slotNumber) {
				slotValueList.PushBack(key)
			}
		}
		fmt.Println(slotValueList.Len())
		// 遍历双向链表
		for e := slotValueList.Front(); e != nil; e = e.Next() {
			fmt.Print(e.Value, " ")
		}
		fmt.Println("-------------")
		slotMap[i] = slotValueList
	}
	return slotMap
}

func (r RedisApi) GetMapCacheAndDelExpire(mapPrefixKey string, expireMsTime int64) (map[string]int64, error) {
	if mapPrefixKey == "" {
		logger.Warn("Cached model GetMapCacheAndDelExpire Object mapPrefixKey is null ")
		return nil, RedisError{"mapPrefixKey is nil", false}
	}
	var mapResult = r.HGetAll(mapPrefixKey)
	if mapResult == nil || mapResult.Err() != nil {
		logger.Warn("RedisApi HGetAll value  is nil or mapKeyValue.Err() is  ", mapResult.Err())
		return nil, RedisError{"RedisApi HGetAll value is nil", false}
	}
	var mapKeyValue, err = mapResult.Result()
	if err != nil || mapKeyValue == nil || len(mapKeyValue) == 0 {
		logger.Warn("RedisApi HGetAll mapResult.Result()  is nil or mapResult.Result().Err() is  ", err)
		return nil, RedisError{"RedisApi HGetAll mapResult.Result() is nil", false}
	}

	keysToDelete := make([]string, 0)
	keyValue := make(map[string]int64, 0)
	for key, value := range mapKeyValue {
		if len(key) <= 0 {
			continue
		}
		valueTime, err := strconv.ParseInt(value, 10, 64)
		//	收集无效的key 或 已过期的key,后期删除
		if err != nil || valueTime-expireMsTime <= 0 {
			logger.Info("Failed to parse value for key %s: %s\n", key, err)
			keysToDelete = append(keysToDelete, key)
			continue
		}
		// 未过期的
		keyValue[key] = valueTime
	}
	//删除已过期的key
	if len(keysToDelete) > 0 {
		err = r.HDel(mapPrefixKey, keysToDelete...).Err()
		if err != nil {
			logger.Warn("Failed to delete keys: [%s] \n, eeror[]", keysToDelete, err)
		}
	}
	return keyValue, nil

}
